home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / wbrun / wbrun.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-09  |  10.3 KB  |  377 lines

  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  2. /* |_o_o|\\ Copyright (c) 1986, 1988 The Software Distillery.                */
  3. /* |. o.| ||   All Rights Reserved. This program may not be distributed      */
  4. /* | .  | ||   without the permission of the authors.                        */
  5. /* | o  | ||  Alan Beale     Jim Cooper        Bruce Drake   Jay Denebeim    */
  6. /* |  . |//   Gordon Keener  John Mainwaring   Jack Rouse    John Toebes     */
  7. /* ======     Doug Walker                              BBS:(919)-471-6436    */
  8. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  9.  
  10. #include <exec/types.h>
  11. #include <exec/memory.h>
  12. #include <workbench/workbench.h>
  13. #include <workbench/icon.h>
  14. #include <workbench/startup.h>
  15. #include <libraries/dos.h>
  16. #include <libraries/dosextens.h>
  17. #include <proto/icon.h>
  18. #include <proto/dos.h>
  19. #include <proto/exec.h>
  20. #include <string.h>
  21. #include "WBRun_rev.h"
  22.  
  23. int setarg(struct WBArg *, char *, BPTR);
  24. void msg(char *, char *);
  25. void main(int, char **);
  26. struct MsgPort *MyCreatePort(char *name,long pri);
  27. extern void __stdargs MemCleanup();
  28. extern void __stdargs _main(register char *line);
  29.  
  30. /*-------------------------------------------------------------------------*/
  31. /* Declarations for CBACK */
  32.  
  33. extern BPTR _Backstdout;         /* standard output when run in background */
  34. long __BackGroundIO = 1;          /* Flag to tell it we want to do I/O      */
  35. long __stack = 4000;              /* Amount of stack space our task needs   */
  36. char *__procname = "WBRun" VERSTAG;     /* The name of the task to create         */
  37. long __priority = 0;              /* The priority to run us at              */
  38.  
  39. #define CSI "\0x9B"
  40.  
  41. struct DosLibrary *DOSBase;
  42. struct Library *MathBase;
  43. struct Library *MathTransBase;
  44.  
  45. struct Library *IconBase;
  46. #define ICON_REV 0
  47.  
  48. #define MAXARG 32              /* maximum command line arguments */
  49. #define QUOTE  '"'
  50.  
  51. #define isspace(c)    ((c == ' ')||(c == '\t') || (c == '\n'))
  52.  
  53. /**
  54. *
  55. * name         _main - process command line, and call "main"
  56. *
  57. * synopsis     _main(line);
  58. *              char *line;     ptr to command line that caused execution
  59. *
  60. * description    This function performs the standard pre-processing for
  61. *        the main module of a C program.  It accepts a command
  62. *        line of the form
  63. *
  64. *            pgmname arg1 arg2 ...
  65. *
  66. *        and builds a list of pointers to each argument.  The first
  67. *        pointer is to the program name.
  68. *
  69. **/
  70. void __stdargs _main(register char *line)
  71. {
  72. register short argc = 0;
  73. register char **pargv;
  74. char *argv[MAXARG];     /* arg pointers */
  75.  
  76. /*
  77. *
  78. * Build argument pointer list
  79. *
  80. */
  81. while (argc < MAXARG)
  82.     {
  83.     while (isspace(*line))    line++;
  84.     if (*line == '\0')    break;
  85.     pargv = &argv[argc++];
  86.     if (*line == QUOTE)
  87.         {
  88.         *pargv = ++line;  /* ptr inside quoted string */
  89.         while ((*line != '\0') && (*line != QUOTE)) line++;
  90.         if (*line == '\0')  return;
  91.         else            *line++ = '\0';  /* terminate arg */
  92.         }
  93.     else        /* non-quoted arg */
  94.         {
  95.         *pargv = line;
  96.         while ((*line != '\0') && (!isspace(*line))) line++;
  97.         if (*line == '\0')  break;
  98.         else             *line++ = '\0';  /* terminate arg */
  99.         }
  100.     }  /* while */
  101.  
  102. main((int)argc,argv);              /* call main function */
  103. }
  104.  
  105. void main(argc, argv)
  106. register int argc;
  107. char **argv;
  108. {
  109. register struct WBStartup *WBStartup;
  110. register struct DiskObject *diskobj;
  111. char *torun, nambuf[160];
  112. register int stacksize, i;
  113. struct Process *ourtask;
  114. struct MsgPort *replyport;
  115. register BPTR olddir, lock;
  116.  
  117. /* initialize so our cleanup routine runs fine */
  118. WBStartup = NULL;
  119. IconBase  = NULL;
  120. diskobj   = NULL;
  121. replyport = NULL;
  122. olddir    = NULL;
  123.  
  124. /* running this from workbench is ridiculous so just quit */
  125. if (argc == 0) return;
  126.  
  127. /* issue the copyright notice - they can supress it by doing a WBRUN >NIL: */
  128. msg( CSI "33m"
  129.      "WBRun II"
  130.      CSI "0m"
  131.      " by John Toebes - Copyright © 1988 The Software Distillery\n",
  132.      "235 Trillingham Ln, Cary NC 27513   BBS:(919)-471-6436");
  133.  
  134. /* not enough parameters? - give them the usage */
  135. if (argc < 2)
  136.    {
  137.    msg(
  138. "Usage: WBRun icon(s)\nWhere icon(s) is to run as if selected from Workbench\n",
  139. "Note: Use WBRun >NIL: icon(s)   to hide copyright message");
  140.    goto done;
  141.    }
  142.  
  143. /* open the libraries we will need */
  144. if ((IconBase = OpenLibrary(ICONNAME, ICON_REV)) == NULL)
  145.    goto done;
  146.  
  147. /* find ourselves - if this doesn't work it deserves to die a horrible */
  148. /* death so I will not even look at our result */
  149. ourtask = (struct Process *)FindTask(NULL);
  150.  
  151. /* allocate storage for all the arguments on the list */
  152. if (((WBStartup = (struct WBStartup *)
  153.                   AllocMem(sizeof(struct WBStartup), MEMF_CLEAR)) == NULL) ||
  154.     ((WBStartup->sm_ArgList = (struct WBArg *)
  155.                      AllocMem(sizeof(struct WBArg)*argc, MEMF_CLEAR)) == NULL) ||
  156.     ((replyport = MyCreatePort("PhoneyWorkbench", 0)) == NULL))
  157.    goto done;
  158.  
  159. /* initialize the remainder of the startup fields */
  160. WBStartup->sm_Message.mn_ReplyPort = replyport;
  161. WBStartup->sm_NumArgs = argc-1;
  162.  
  163. /* run through all the arguments getting locks and names for them */
  164. for (i=1; i<argc; i++)
  165.    if (setarg(&WBStartup->sm_ArgList[i-1], argv[i],ourtask->pr_CurrentDir))
  166.          goto done;
  167.  
  168. /*-- Load the code that is desired ---*/
  169. /* to do this, first find the program to be run */
  170. olddir = CurrentDir( WBStartup->sm_ArgList[0].wa_Lock );
  171.  
  172. if ((diskobj = (struct DiskObject *)
  173.                GetDiskObject( WBStartup->sm_ArgList[0].wa_Name )) == NULL)
  174.    {
  175.    msg("Can't get icon for ", WBStartup->sm_ArgList[0].wa_Name);
  176.    goto done;
  177.    }
  178.  
  179. torun = argv[1];
  180.  
  181. /* once we have the object, look at the tool type */
  182. /* for TOOLS we run the program (argv[0] in our case) */
  183. /* For projects it has the name of the default tool to run with it */
  184. /* all others are to be blown away */
  185. if (diskobj->do_Type == WBPROJECT)
  186.    {
  187.    /* for a project, we need to insert the tool icon as the first tool */
  188.    /* move everything over one */
  189.    for (i=1; i<argc; i++)
  190.       memcpy((char *)&WBStartup->sm_ArgList[i-1],
  191.              (char *)&WBStartup->sm_ArgList[i],
  192.               sizeof(struct WBArg));
  193.    strcpy(nambuf, diskobj->do_DefaultTool);
  194.    torun = nambuf;
  195.  
  196.    if (setarg(&WBStartup->sm_ArgList[0], torun, olddir))
  197.       goto done;
  198.  
  199.    FreeDiskObject(diskobj);
  200.  
  201.    if ((diskobj = (struct DiskObject *)
  202.                   GetDiskObject( WBStartup->sm_ArgList[0].wa_Name )) == NULL)
  203.       {
  204.       msg("Can't get icon for ", WBStartup->sm_ArgList[0].wa_Name);
  205.       goto done;
  206.       }
  207.  
  208.    WBStartup->sm_NumArgs++;
  209.    }
  210.  
  211. /* at this point if it is not a TOOL we are scrod */
  212. if (diskobj->do_Type != WBTOOL)
  213.    {
  214.    msg("Icon is not runnable for ", torun);
  215.    goto done;
  216.    }
  217.  
  218. if ((stacksize = diskobj->do_StackSize) < 4000)
  219.    stacksize = 4000;
  220.  
  221. /* so lets load the segment for the program to run */
  222. if ((WBStartup->sm_Segment = LoadSeg(torun)) == NULL)
  223.    {
  224.    msg("Can't open tool ", torun);
  225.    goto done;
  226.    }
  227.  
  228. /* also we will need to get it going as a process */
  229. if ((WBStartup->sm_Process = (struct MsgPort *)
  230.            CreateProc(torun, 0, WBStartup->sm_Segment, stacksize)) == NULL)
  231.    {
  232.    msg("Can't create process for ", torun);
  233.    goto done;
  234.    }
  235.  
  236. /* we are off and running, pass it the message to get running */
  237. WBStartup->sm_ToolWindow = diskobj->do_ToolWindow;
  238.  
  239. PutMsg((struct MsgPort *)WBStartup->sm_Process, (struct Message *)WBStartup);
  240.  
  241. /* when he is done with what he needs, we can blow everything away */
  242. WaitPort(replyport);
  243.  
  244. /* everything is now complete so clean up and go away */
  245. done:
  246. if (_Backstdout) Close(_Backstdout);
  247. _Backstdout = NULL;
  248.  
  249. if (replyport != NULL) DeletePort(replyport);
  250. replyport = NULL;
  251.  
  252. if (diskobj != NULL) FreeDiskObject(diskobj);
  253. diskobj = NULL;
  254.  
  255. if (olddir != NULL) CurrentDir(olddir);
  256.  
  257. if (WBStartup != NULL)
  258.    {
  259.    if (WBStartup->sm_Segment != NULL)
  260.       UnLoadSeg(WBStartup->sm_Segment);
  261.    if (WBStartup->sm_ArgList != NULL)
  262.       {
  263.       /* run through and free any locks we may have */
  264.       for (i=0; i<argc; i++)
  265.          {
  266.          lock = WBStartup->sm_ArgList[i].wa_Lock;
  267.          if ((lock != NULL) && (lock != ourtask->pr_CurrentDir))
  268.             UnLock(lock);
  269.          }
  270.       FreeMem((char *)(WBStartup->sm_ArgList),sizeof(struct WBArg)*argc);
  271.       }
  272.    FreeMem((char *)WBStartup, sizeof(struct WBStartup));
  273.    }
  274. WBStartup = NULL;
  275.  
  276. if (IconBase != NULL) CloseLibrary(IconBase);
  277. IconBase = NULL;
  278.  
  279. }
  280.  
  281. /***********************************************************/
  282. /* given a null terminated name, fill in a WBArg structure */
  283. /* with a lock and a name relative to that lock            */
  284. /***********************************************************/
  285. int setarg(WBArg, name, curdir)
  286. register struct WBArg *WBArg;
  287. char *name;
  288. BPTR curdir;
  289. {
  290. register char *p, *lastc;
  291. register unsigned char c;
  292.  
  293. if (name == NULL || !*name) return(1);  /* bad name to use */
  294.  
  295. /* first find the last colon or slash in the name */
  296. lastc = NULL;
  297. for (p = name; *p; p++)
  298.    if (*p == ':' || *p == '/')
  299.       lastc = p+1;
  300.  
  301. /* was there a path delimiter at all ? */
  302. if (lastc == NULL)
  303.    {
  304.    /* no, use the default lock and full name */
  305.    WBArg->wa_Lock = curdir;
  306.    WBArg->wa_Name = name;
  307.    }
  308. else
  309.    {
  310.    /* must get a lock on the right directory and use part of the name */
  311.    if (!*lastc) return(1); /* only a drawer specified */
  312.    WBArg->wa_Name = lastc;
  313.  
  314.    /* when setting a directory, we need to include the delimiter */
  315.    c = *lastc;
  316.    *lastc = NULL;
  317.    if ((WBArg->wa_Lock = Lock(name, ACCESS_READ)) == NULL)
  318.       {
  319.       msg("Can't open directory:", name);
  320.       return(1);  /* couldn't find the director */
  321.       }
  322.    *lastc++ = c;
  323.    }
  324.  
  325. /* it worked so let them continue on */
  326. return(0);
  327. }
  328.  
  329. void msg(str1, str2)
  330. char *str1, *str2;
  331. {
  332. if (_Backstdout)
  333.    {
  334.    Write(_Backstdout,str1,strlen(str1));
  335.    Write(_Backstdout,str2,strlen(str2));
  336.    Write(_Backstdout,"\n", 1);
  337.    }
  338. }
  339.  
  340. void __stdargs MemCleanup(void) {
  341. }
  342.  
  343. struct MsgPort *MyCreatePort(char *name,long pri)
  344. {
  345. register UBYTE sigbit;
  346. register struct MsgPort *port;
  347.  
  348. if ((sigbit = AllocSignal(-1)) == -1)
  349.    return(NULL);
  350.  
  351. if ((port = (struct MsgPort *)
  352.             AllocMem(sizeof(struct MsgPort), MEMF_CLEAR|MEMF_PUBLIC)) == NULL)
  353.    {
  354.    FreeSignal(sigbit);
  355.    return(NULL);
  356.    }
  357.  
  358. port->mp_Node.ln_Name = name;
  359. port->mp_Node.ln_Pri = pri;
  360. port->mp_Node.ln_Type = NT_MSGPORT;
  361. port->mp_Flags = PA_SIGNAL;
  362. port->mp_SigBit = sigbit;
  363. port->mp_SigTask = FindTask(0);
  364.  
  365. AddPort(port);
  366.  
  367. return(port);
  368. }
  369.  
  370. void DeletePort(port)
  371. register struct MsgPort *port;
  372. {
  373. RemPort(port);
  374. FreeSignal(port->mp_SigBit);
  375. FreeMem((char *)port, sizeof(struct MsgPort));
  376. }
  377.